package net.siufung.simple.config.security.interceptor;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.expression.LongValue;
import net.siufung.core.model.consts.Constants;
import net.siufung.mybatis.properties.MybatisProperties;
import net.siufung.security.api.AuthUtil;
import net.siufung.security.api.context.TenantContextHolder;
import net.siufung.security.api.context.UserContextHolder;
import net.siufung.security.api.service.IAccessTokenService;
import org.springframework.http.HttpHeaders;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;
import java.util.Date;

/**
 * 配置用户会话拦截器
 * @author 陈建峰
 * @since 2022/5/6 4:54 下午
 */
@Slf4j
@RequiredArgsConstructor
public class SecurityHandlerInterceptor implements HandlerInterceptor {

    @NotNull
    private final IAccessTokenService accessTokenService;
    @NotNull
    private final MybatisProperties mybatisProperties;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        UserContextHolder.getInstance().clear();
        if(mybatisProperties.getTenant().isEnable()){
            TenantContextHolder.getInstance().clear();
        }
        String token = request.getHeader(HttpHeaders.AUTHORIZATION);
        String path = request.getServletPath();
        if(!accessTokenService.ignoreUrlForToken(path)) {
            JSONObject jwtTokenObj = accessTokenService.getValidTokenObj(token);
            UserContextHolder.getInstance().setContext(ObjectUtil.defaultIfNull(jwtTokenObj, new JSONObject()));
            if(mybatisProperties.getTenant().isEnable()){
                String tenantEnable = request.getHeader(Constants.AUTH_CLIENT_TENANT_ENABLE);
                if(StrUtil.isNotBlank(tenantEnable) && Convert.toBool(tenantEnable)){
                    TenantContextHolder.getInstance().setTenantId(new LongValue(AuthUtil.getTenantId()));
                }
            }
            //Token延长10分钟
            accessTokenService.setExpirationDate(
                    StrUtil.subSuf(token, Constants.BEARER.length()), DateUtil.offsetMinute(new Date(), 10));
        }
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
        UserContextHolder.getInstance().clear();
        if(mybatisProperties.getTenant().isEnable()){
            TenantContextHolder.getInstance().clear();
        }
    }
}
